/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.tbp.persitence.dao.impl;

import br.com.tbp.exception.PersistenciaException;
import br.com.tbp.model.domain.Consultor;
import br.com.tbp.model.domain.Pedido;
import br.com.tbp.model.domain.constant.TipoConsultor;
import br.com.tbp.model.domain.financeiro.AjudaCusto;
import br.com.tbp.model.domain.financeiro.StatusAjuda;
import br.com.tbp.persitence.GerenciadorDeConexao;
import br.com.tbp.persitence.dao.AjudaCustoDao;
import br.com.tbp.utils.DateUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 *
 * @author Diego
 */
public class AjudaCustoDaoImpl implements AjudaCustoDao {

    private Connection conn = null;
    private PreparedStatement pr = null;
    private ResultSet rs = null;

    public void adicionar(AjudaCusto ajuda) throws PersistenciaException {
        if (ajuda == null) {
            throw new PersistenciaException("Não foi informado a ajuda de custo a cadastrar.");
        }

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement("INSERT INTO AJUDA_CUSTO VALUES(NULL, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?)",
                    Statement.RETURN_GENERATED_KEYS);
            pr.setString(1, ajuda.getDescricao());
            pr.setDate(2, DateUtils.dataObjetoParaDataBancoDeDados(ajuda.getDataLiberacao()));
            pr.setLong(3, ajuda.getConsultor() != null ? ajuda.getConsultor().getId() : 0);
            pr.setDouble(4, ajuda.getValor());
            pr.setInt(5, ajuda.getAcessos());
            pr.setString(6, ajuda.getStatus().name());
            pr.setString(7, ajuda.getObservacao());
            pr.setInt(8, ajuda.getFechamento());
            pr.setString(9, ajuda.getTipo().name());
            pr.executeUpdate();

            rs = pr.getGeneratedKeys();
            rs.next();
            long id = rs.getLong(1);
            ajuda.setId(id);

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível cadastrar a ajuda de custo.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }
    }

    //Desativado
    @Deprecated
    public void atualizar(AjudaCusto ajuda) throws PersistenciaException {
        if (ajuda == null) {
            throw new PersistenciaException("Não foi informado a ajuda de custo a atualizar.");
        }

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement("UPDATE AJUDA_CUSTO SET DESCRICAO=?,DATA=?,ID_CONSULTOR=?,VALOR=?,ACESSOS=?,STATUS=?,OBSERVACAO=?,FECHAMENTO=? WHERE ID=?");
            pr.setString(1, ajuda.getDescricao());
            pr.setDate(2, DateUtils.dataObjetoParaDataBancoDeDados(ajuda.getDataLiberacao()));
            pr.setLong(3, ajuda.getConsultor() != null ? ajuda.getConsultor().getId() : 0);
            pr.setDouble(4, ajuda.getValor());
            pr.setInt(5, ajuda.getAcessos());
            pr.setString(6, ajuda.getStatus().name());
            pr.setString(7, ajuda.getObservacao());
            pr.setInt(8, ajuda.getFechamento());
            pr.setLong(9, ajuda.getId());
            pr.executeUpdate();

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível atualizar a ajuda de custo.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }
    }

    public List<AjudaCusto> pesquisar(String consultor) throws PersistenciaException {
        List<AjudaCusto> lista = new ArrayList<AjudaCusto>();

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement("SELECT A.ID, A.DESCRICAO, A.DATA, A.VALOR, A.ACESSOS, A.STATUS, A.OBSERVACAO, A.FECHAMENTO, A.DATA_FECHAMENTO, A.TIPO_CONSULTOR, C.ID_CONSULTOR, C.NOME AS NOME_CONSULTOR FROM AJUDA_CUSTO A INNER JOIN CONSULTOR C ON A.ID_CONSULTOR = C.ID_CONSULTOR WHERE C.NOME LIKE ? ORDER BY C.NOME;");
            pr.setString(1, "%" + consultor + "%");
            rs = pr.executeQuery();

            if (rs != null) {
                while (rs.next()) {
                    AjudaCusto c = this.criarAjudaCusto(rs);
                    lista.add(c);
                }
            }

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível pesquisar as ajudas de custo por consultor.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }

        return lista;
    }

    public List<AjudaCusto> pesquisar(StatusAjuda status) throws PersistenciaException {
        List<AjudaCusto> lista = new ArrayList<AjudaCusto>();

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement("SELECT A.ID, A.DESCRICAO, A.DATA, A.VALOR, A.ACESSOS, A.STATUS, A.OBSERVACAO, A.FECHAMENTO, A.DATA_FECHAMENTO, A.TIPO_CONSULTOR, C.ID_CONSULTOR, C.NOME AS NOME_CONSULTOR FROM AJUDA_CUSTO A INNER JOIN CONSULTOR C ON A.ID_CONSULTOR = C.ID_CONSULTOR WHERE A.STATUS=? ORDER BY A.DATA;");
            pr.setString(1, status.name());
            rs = pr.executeQuery();

            if (rs != null) {
                while (rs.next()) {
                    AjudaCusto c = this.criarAjudaCusto(rs);
                    lista.add(c);
                }
            }

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível pesquisar as ajudas de custo por status.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }

        return lista;
    }

    public List<AjudaCusto> pesquisar(Date data1, Date data2) throws PersistenciaException {
        List<AjudaCusto> lista = new ArrayList<AjudaCusto>();

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement("SELECT A.ID, A.DESCRICAO, A.DATA, A.VALOR, A.ACESSOS, A.STATUS, A.OBSERVACAO, A.FECHAMENTO, A.DATA_FECHAMENTO, A.TIPO_CONSULTOR, C.ID_CONSULTOR, C.NOME AS NOME_CONSULTOR FROM AJUDA_CUSTO A INNER JOIN CONSULTOR C ON A.ID_CONSULTOR = C.ID_CONSULTOR WHERE A.DATA BETWEEN ? AND ? ORDER BY A.DATA;");
            pr.setDate(1, new java.sql.Date(data1.getTime()));
            pr.setDate(2, data2 != null ? new java.sql.Date(data2.getTime()) : new java.sql.Date(data1.getTime()));
            rs = pr.executeQuery();

            if (rs != null) {
                while (rs.next()) {
                    AjudaCusto c = this.criarAjudaCusto(rs);
                    lista.add(c);
                }
            }

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível pesquisar as ajudas de custo por período.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }

        return lista;
    }

    public void remover(AjudaCusto ajuda) throws PersistenciaException {
        if (ajuda == null) {
            throw new PersistenciaException("Não foi informado a ajuda de custo a remover.");
        }

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement("DELETE FROM AJUDA_CUSTO WHERE ID=?");
            pr.setLong(1, ajuda.getId());
            pr.executeUpdate();

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível remover a ajuda de custo.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }
    }

    private AjudaCusto criarAjudaCusto(ResultSet rs) throws PersistenciaException {
        AjudaCusto ajuda = null;
        try {
            ajuda = new AjudaCusto(rs.getLong("ID"));
            ajuda.setDescricao(rs.getString("DESCRICAO"));
            ajuda.setDataLiberacao(new Date(rs.getDate("DATA").getTime()));
            ajuda.setConsultor(new Consultor(rs.getLong("ID_CONSULTOR"), rs.getString("NOME_CONSULTOR")));
            ajuda.setValor(rs.getDouble("VALOR"));
            ajuda.setAcessos(rs.getInt("ACESSOS"));
            ajuda.setStatus(StatusAjuda.valueOf(rs.getString("STATUS")));
            ajuda.setObservacao(rs.getString("OBSERVACAO"));
            ajuda.setFechamento(rs.getInt("FECHAMENTO"));
            ajuda.setDataFechamento(rs.getDate("data_fechamento") != null ? new Date(rs.getDate("data_fechamento").getTime()) : null);
            ajuda.setTipo(TipoConsultor.valueOf(rs.getString("TIPO_CONSULTOR")));
        } catch (SQLException sqlex) {
            StringBuilder msg = new StringBuilder("Não foi possível obter os dados da ajuda de custo.");
            msg.append("\nMotivo: ").append(sqlex.getMessage());
            throw new PersistenciaException(msg.toString());
        }
        return ajuda;
    }

    public boolean isLiberarAjuda(Consultor consultor) throws PersistenciaException {
        boolean liberar = true;
        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement("SELECT ID FROM AJUDA_CUSTO WHERE ID_CONSULTOR=? AND STATUS='PENDENTE';");
            pr.setLong(1, consultor.getId());
            rs = pr.executeQuery();

            if (rs != null) {
                if (rs.first()) {
                    liberar = false;
                }
            }

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível verificar a liberação de ajuda de custo.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }
        return liberar;
    }

    public void baixarAjudaDeCusto(Pedido pedido) throws PersistenciaException {
        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement("SELECT ID, ACESSOS, FECHAMENTO FROM AJUDA_CUSTO WHERE ID_CONSULTOR=? AND STATUS='PENDENTE'");
            pr.setLong(1, pedido.getConsultor().getId());
            rs = pr.executeQuery();

            if (rs != null) {
                if (rs.first()) {
                    AjudaCusto ajudaCusto = new AjudaCusto(rs.getLong("ID"), rs.getInt("ACESSOS"), rs.getInt("FECHAMENTO"));
                    ajudaCusto.adicionarAcessos(pedido.qtde_de_itens());

                    pr = conn.prepareStatement("UPDATE AJUDA_CUSTO SET FECHAMENTO=?, STATUS=?, DATA_FECHAMENTO=? WHERE ID=?;");
                    pr.setInt(1, ajudaCusto.getFechamento());
                    pr.setString(2, ajudaCusto.getStatus().name());
                    pr.setDate(3, ajudaCusto.getDataFechamento() != null ? new java.sql.Date(ajudaCusto.getDataFechamento().getTime()) : null);
                    pr.setLong(4, ajudaCusto.getId());
                    pr.executeUpdate();
                }
            }

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível dar baixar na ajuda de custo.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }
    }
}
